
#include <string>
#include <sstream>
#include <iostream>
#include "../../utils/log.h"
#include "../../utils/BOOL.h"
#include "SQLParser.h"
#include "../../utils/StringUtils.h"
#include "../../utils/FnvHash.h"

bool SQLParser::identifierEquals(string_ptr text)
{
  std::wstring tmp = encode_util::UTF8ToUnicode(*text);
  return lexer->identifierEquals(tmp);
}

bool SQLParser::identifierEquals(const char *text)
{
  std::string tmp_str = text;
  std::wstring tmp = encode_util::UTF8ToUnicode(tmp_str);
  return lexer->identifierEquals(tmp);
}

SQLParser::~SQLParser()
{

  // std::cout << __FILE__ << ": " << __LINE__ << ", in SQLParser::~SQLParser, destructor step 1" << std::endl;
  // if (lexerHere && lexer != NULL)
  // {
  // std::cout << __FILE__ << ": " << __LINE__ << ", in SQLParser::~SQLParser, destructor step 1.1" << std::endl;
  // delete lexer;
  // }
  // std::cout << __FILE__ << ": " << __LINE__ << ", in SQLParser::~SQLParser, destructor step 2" << std::endl;
}

void SQLParser::acceptIdentifier(string_ptr text)
{
  if (identifierEquals(text))
  {
    lexer->nextToken();
  }
  else
  {
    setErrorEndPos(lexer->pos());

    std::stringstream stream;
    stream << "syntax error, expect " << text << ", actual " << lexer->token();

    throw new ParserException(make_string_ptr(stream.str()));
  }
}
void SQLParser::acceptIdentifier(const char *text)
{
  LOG_INFO;
  if (identifierEquals(text))
  {
    lexer->nextToken();
  }
  else
  {
    setErrorEndPos(lexer->pos());

    std::stringstream stream;
    stream << "syntax error, expect " << text << ", actual " << lexer->token();

    throw new ParserException(make_string_ptr(stream.str()));
  }
}

string_ptr SQLParser::as()
{
  // http://stackoverflow.com/questions/3903587/how-to-check-if-a-stdstring-is-set-or-not
  LOG_INFO << ": token name:" << lexer->token()->getName();
  string_ptr alias = make_string_ptr("");

  if (lexer->token()->name->c_str() == Token::COMMA.name->c_str())
  {
    string_ptr tmp = make_string_ptr("");
    return tmp;
  }

  if (lexer->token()->name->c_str() == Token::AS.name->c_str())
  {
    lexer->nextToken();

    if (lexer->token()->name->c_str() == Token::LITERAL_ALIAS.name->c_str())
    {
      alias = make_string_ptr('"' + encode_util::UnicodeToUTF8(*lexer->stringVal()).c_str() + '"');
      lexer->nextToken();
    }
    else if (lexer->token()->name->c_str() == Token::IDENTIFIER.name->c_str())
    {
      alias = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
      lexer->nextToken();
    }
    else if (lexer->token()->name->c_str() == Token::LITERAL_CHARS.name->c_str())
    {
      alias = make_string_ptr('\'' + encode_util::UnicodeToUTF8(*lexer->stringVal()).c_str() + '\'');
      lexer->nextToken();
    }
    else
    {
      if (lexer->token()->name->c_str() == Token::KEY.name->c_str() ||
          lexer->token()->name->c_str() == Token::INDEX.name->c_str() ||
          lexer->token()->name->c_str() == Token::CASE.name->c_str() ||
          lexer->token()->name->c_str() == Token::PCTFREE.name->c_str() ||
          lexer->token()->name->c_str() == Token::INITRANS.name->c_str() ||
          lexer->token()->name->c_str() == Token::MAXTRANS.name->c_str() ||
          lexer->token()->name->c_str() == Token::SEGMENT.name->c_str() ||
          lexer->token()->name->c_str() == Token::CREATION.name->c_str() ||
          lexer->token()->name->c_str() == Token::IMMEDIATE.name->c_str() ||
          lexer->token()->name->c_str() == Token::DEFERRED.name->c_str() ||
          lexer->token()->name->c_str() == Token::STORAGE.name->c_str() ||
          lexer->token()->name->c_str() == Token::NEXT.name->c_str() ||
          lexer->token()->name->c_str() == Token::MINEXTENTS.name->c_str() ||
          lexer->token()->name->c_str() == Token::MAXEXTENTS.name->c_str() ||
          lexer->token()->name->c_str() == Token::MAXSIZE.name->c_str() ||
          lexer->token()->name->c_str() == Token::PCTINCREASE.name->c_str() ||
          lexer->token()->name->c_str() == Token::FLASH_CACHE.name->c_str() ||
          lexer->token()->name->c_str() == Token::CELL_FLASH_CACHE.name->c_str() ||
          lexer->token()->name->c_str() == Token::NONE.name->c_str() ||
          lexer->token()->name->c_str() == Token::LOB.name->c_str() ||
          lexer->token()->name->c_str() == Token::STORE.name->c_str() ||
          lexer->token()->name->c_str() == Token::ROW.name->c_str() ||
          lexer->token()->name->c_str() == Token::CHUNK.name->c_str() ||
          lexer->token()->name->c_str() == Token::CACHE.name->c_str() ||
          lexer->token()->name->c_str() == Token::NOCACHE.name->c_str() ||
          lexer->token()->name->c_str() == Token::LOGGING.name->c_str() ||
          lexer->token()->name->c_str() == Token::NOCOMPRESS.name->c_str() ||
          lexer->token()->name->c_str() == Token::KEEP_DUPLICATES.name->c_str() ||
          lexer->token()->name->c_str() == Token::EXCEPTIONS.name->c_str() ||
          lexer->token()->name->c_str() == Token::PURGE.name->c_str() ||
          lexer->token()->name->c_str() == Token::INITIALLY.name->c_str() ||
          lexer->token()->name->c_str() == Token::END.name->c_str() ||
          lexer->token()->name->c_str() == Token::COMMENT.name->c_str() ||
          lexer->token()->name->c_str() == Token::ENABLE.name->c_str() ||
          lexer->token()->name->c_str() == Token::DISABLE.name->c_str() ||
          lexer->token()->name->c_str() == Token::SEQUENCE.name->c_str() ||
          lexer->token()->name->c_str() == Token::USER.name->c_str() ||
          lexer->token()->name->c_str() == Token::ANALYZE.name->c_str() ||
          lexer->token()->name->c_str() == Token::OPTIMIZE.name->c_str() ||
          lexer->token()->name->c_str() == Token::GRANT.name->c_str() ||
          lexer->token()->name->c_str() == Token::FULL.name->c_str() ||
          lexer->token()->name->c_str() == Token::TO.name->c_str() ||
          lexer->token()->name->c_str() == Token::NEW.name->c_str() ||
          lexer->token()->name->c_str() == Token::INTERVAL.name->c_str() ||
          lexer->token()->name->c_str() == Token::LOCK.name->c_str() ||
          lexer->token()->name->c_str() == Token::LIMIT.name->c_str() ||
          lexer->token()->name->c_str() == Token::IDENTIFIED.name->c_str() ||
          lexer->token()->name->c_str() == Token::PASSWORD.name->c_str() ||
          lexer->token()->name->c_str() == Token::BINARY.name->c_str() ||
          lexer->token()->name->c_str() == Token::WINDOW.name->c_str() ||
          lexer->token()->name->c_str() == Token::OFFSET.name->c_str() ||
          lexer->token()->name->c_str() == Token::SHARE.name->c_str() ||
          lexer->token()->name->c_str() == Token::START.name->c_str() ||
          lexer->token()->name->c_str() == Token::CONNECT.name->c_str() ||
          lexer->token()->name->c_str() == Token::MATCHED.name->c_str() ||
          lexer->token()->name->c_str() == Token::ERRORS.name->c_str() ||
          lexer->token()->name->c_str() == Token::REJECT.name->c_str() ||
          lexer->token()->name->c_str() == Token::UNLIMITED.name->c_str() ||
          lexer->token()->name->c_str() == Token::BEGIN.name->c_str() ||
          lexer->token()->name->c_str() == Token::EXCLUSIVE.name->c_str() ||
          lexer->token()->name->c_str() == Token::MODE.name->c_str() ||
          lexer->token()->name->c_str() == Token::ADVISE.name->c_str())
      {
        alias = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
        lexer->nextToken();
        return alias;
      }
      else if (lexer->token()->name->c_str() == Token::QUES.name->c_str())
      {
        alias = make_string_ptr("?");
        lexer->nextToken();
      }
    }

    if (!alias->empty())
    {
      while (lexer->token()->name->c_str() == Token::DOT.name->c_str())
      {
        lexer->nextToken();
        alias->append('.' + *lexer->token()->getName());
        lexer->nextToken();
      }

      return alias;
    }

    if (lexer->token()->name->c_str() == Token::LPAREN.name->c_str())
    {
      // return NULL;
      alias = make_string_ptr("");
      return alias;
    }

    string_ptr tmp = make_string_ptr("Error : ");
    // tmp += lexer->token();
    throw new ParserException(tmp);
  }

  if (lexer->token()->name->c_str() == Token::LITERAL_ALIAS.name->c_str())
  {
    alias = make_string_ptr('"' + encode_util::UnicodeToUTF8(*lexer->stringVal()).c_str() + '"');
    lexer->nextToken();
  }
  else if (lexer->token()->name->c_str() == Token::IDENTIFIER.name->c_str())
  {
    alias = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
    lexer->nextToken();
  }
  else if (lexer->token()->name->c_str() == Token::LITERAL_CHARS.name->c_str())
  {
    alias = make_string_ptr('\'' + encode_util::UnicodeToUTF8(*lexer->stringVal()).c_str() + '\'');
    lexer->nextToken();
  }
  else
  {
    if (lexer->token()->name->c_str() == Token::CASE.name->c_str() ||
        lexer->token()->name->c_str() == Token::USER.name->c_str() ||
        lexer->token()->name->c_str() == Token::LOB.name->c_str() ||
        lexer->token()->name->c_str() == Token::END.name->c_str() ||
        lexer->token()->name->c_str() == Token::DEFERRED.name->c_str() ||
        lexer->token()->name->c_str() == Token::OUTER.name->c_str() ||
        lexer->token()->name->c_str() == Token::DO.name->c_str() ||
        lexer->token()->name->c_str() == Token::LOOP.name->c_str() ||
        lexer->token()->name->c_str() == Token::STORE.name->c_str() ||
        lexer->token()->name->c_str() == Token::MOD.name->c_str() ||
        lexer->token()->name->c_str() == Token::ANY.name->c_str() ||
        lexer->token()->name->c_str() == Token::BEGIN.name->c_str() ||
        lexer->token()->name->c_str() == Token::CAST.name->c_str() ||
        lexer->token()->name->c_str() == Token::COMPUTE.name->c_str() ||
        lexer->token()->name->c_str() == Token::ESCAPE.name->c_str() ||
        lexer->token()->name->c_str() == Token::FULL.name->c_str() ||
        lexer->token()->name->c_str() == Token::MERGE.name->c_str() ||
        lexer->token()->name->c_str() == Token::OPEN.name->c_str() ||
        lexer->token()->name->c_str() == Token::SOME.name->c_str() ||
        lexer->token()->name->c_str() == Token::TRUNCATE.name->c_str() ||
        lexer->token()->name->c_str() == Token::UNTIL.name->c_str() ||
        lexer->token()->name->c_str() == Token::VIEW.name->c_str() ||
        lexer->token()->name->c_str() == Token::KILL.name->c_str() ||
        lexer->token()->name->c_str() == Token::COMMENT.name->c_str() ||
        lexer->token()->name->c_str() == Token::TABLESPACE.name->c_str() ||
        lexer->token()->name->c_str() == Token::REPEAT.name->c_str() ||
        lexer->token()->name->c_str() == Token::PRIMARY.name->c_str() ||
        lexer->token()->name->c_str() == Token::FOREIGN.name->c_str() ||
        lexer->token()->name->c_str() == Token::UNIQUE.name->c_str() ||
        lexer->token()->name->c_str() == Token::LEAVE.name->c_str() ||
        lexer->token()->name->c_str() == Token::ENABLE.name->c_str() ||
        lexer->token()->name->c_str() == Token::DISABLE.name->c_str() ||
        lexer->token()->name->c_str() == Token::REPLACE.name->c_str())
    {
      alias = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
      lexer->nextToken();
    }
    else if (lexer->token()->name->c_str() == Token::INTERSECT.name->c_str() ||
             lexer->token()->name->c_str() == Token::EXCEPT.name->c_str() ||
             lexer->token()->name->c_str() == Token::DESC.name->c_str() ||
             lexer->token()->name->c_str() == Token::INOUT.name->c_str() ||
             lexer->token()->name->c_str() == Token::MINUS.name->c_str() ||
             lexer->token()->name->c_str() == Token::UPDATE.name->c_str() ||
             lexer->token()->name->c_str() == Token::DELETE.name->c_str() ||
             lexer->token()->name->c_str() == Token::TABLE.name->c_str() ||
             lexer->token()->name->c_str() == Token::UNION.name->c_str() ||
             lexer->token()->name->c_str() == Token::EXPLAIN.name->c_str() ||
             lexer->token()->name->c_str() == Token::CREATE.name->c_str() ||
             lexer->token()->name->c_str() == Token::LIMIT.name->c_str() ||
             lexer->token()->name->c_str() == Token::USE.name->c_str() ||
             lexer->token()->name->c_str() == Token::BY.name->c_str() ||
             lexer->token()->name->c_str() == Token::ALTER.name->c_str() ||
             lexer->token()->name->c_str() == Token::IN.name->c_str() ||
             lexer->token()->name->c_str() == Token::INTO.name->c_str() ||
             lexer->token()->name->c_str() == Token::ASC.name->c_str())
    {
      alias = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));

      Lexer_SavePoint_ptr mark = lexer->mark();
      lexer->nextToken();
      if (lexer->token()->name->c_str() != Token::COMMA.name->c_str() &&
          lexer->token()->name->c_str() != Token::RPAREN.name->c_str() &&
          lexer->token()->name->c_str() != Token::FROM.name->c_str() &&
          lexer->token()->name->c_str() != Token::SEMI.name->c_str() &&
          lexer->token()->name->c_str() != Token::SEMI.name->c_str())
      {
        alias = make_string_ptr("");
        lexer->reset(mark);
      }
    }
    else if (lexer->token()->name->c_str() == Token::CHECK.name->c_str() ||
             lexer->token()->name->c_str() == Token::INDEX.name->c_str() ||
             lexer->token()->name->c_str() == Token::ALL.name->c_str() ||
             lexer->token()->name->c_str() == Token::INNER.name->c_str() ||
             lexer->token()->name->c_str() == Token::CLOSE.name->c_str() ||
             lexer->token()->name->c_str() == Token::VALUES.name->c_str() ||
             lexer->token()->name->c_str() == Token::SHOW.name->c_str() ||
             lexer->token()->name->c_str() == Token::SEQUENCE.name->c_str() ||
             lexer->token()->name->c_str() == Token::TO.name->c_str() ||
             lexer->token()->name->c_str() == Token::REFERENCES.name->c_str() ||
             lexer->token()->name->c_str() == Token::LIKE.name->c_str() ||
             lexer->token()->name->c_str() == Token::RLIKE.name->c_str() ||
             lexer->token()->name->c_str() == Token::XNULL.name->c_str() ||
             lexer->token()->name->c_str() == Token::RIGHT.name->c_str() ||
             lexer->token()->name->c_str() == Token::LEFT.name->c_str() ||
             lexer->token()->name->c_str() == Token::DATABASE.name->c_str())
    {
      if (dbType->name->c_str() == DbType::odps.name->c_str() ||
          dbType->name->c_str() == DbType::hive.name->c_str())
      {
        alias = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
        lexer->nextToken();
      }
    }
    else if (lexer->token()->name->c_str() == Token::GROUP.name->c_str() ||
             lexer->token()->name->c_str() == Token::ORDER.name->c_str() ||
             lexer->token()->name->c_str() == Token::DISTRIBUTE.name->c_str() ||
             lexer->token()->name->c_str() == Token::DEFAULT.name->c_str())
    {
      if (dbType->name->c_str() == DbType::odps.name->c_str() ||
          dbType->name->c_str() == DbType::hive.name->c_str())
      {
        Lexer_SavePoint_ptr mark = lexer->mark();
        alias = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
        lexer->nextToken();
        if (lexer->token()->name->c_str() == Token::BY.name->c_str())
        {
          lexer->reset(mark);
          alias = make_string_ptr("");
        }
      }
    }
  }
  LOG_INFO << ": token name:" << lexer->token()->getName();
  if (lexer->token()->name->c_str() == Token::KEY.name->c_str() ||
      lexer->token()->name->c_str() == Token::INTERVAL.name->c_str() ||
      lexer->token()->name->c_str() == Token::CONSTRAINT.name->c_str())
  {
    alias = lexer->token()->getName();
    lexer->nextToken();
    return alias;
  }
  LOG_INFO << ": token name:" << lexer->token()->getName();
  if (isEnabled(SQLParserFeature_ptr(new SQLParserFeature(SQLParserFeature::IgnoreNameQuotes.mask, SQLParserFeature::IgnoreNameQuotes.name))) &&
      !alias->empty() &&
      alias->length() > 1)
  {
    alias = StringUtils::removeNameQuotes(alias);
  }
  LOG_INFO << ": alias:" << alias;
  return alias;
}

void SQLParser::setErrorEndPos(int errPos)
{
  if (errPos > errorEndPos)
  {
    errorEndPos = errPos;
  }
}

SQLParser::SQLParser()
{
  errorEndPos = -1;
}

SQLParser::SQLParser(string_ptr sql)
    : lexerHere(BOOL::TRUE),
      lexer((new Lexer(encode_util::UTF8ToUnicode(*sql)))),
      errorEndPos(-1)
{

  // std::cout << __FILE__ << ": " << __LINE__ << ", in SQLParser::SQLParser, constructor 1 " << std::endl;
  // this(new Lexer(sql));
  // this.lexer->nextToken();
  // Lexer_ptr theLexer = new Lexer(sql);
  // lexer = *theLexer;
  lexer->nextToken();
}

SQLParser::SQLParser(Lexer_ptr theLexer)
    : lexerHere(BOOL::FALSE),
      lexer(theLexer),
      errorEndPos(-1)
{
  LOG_INFO;
  // std::cout << __FILE__ << ": " << __LINE__ << ", in SQLParser::SQLParser, constructor 2 " << std::endl;
  // lexer = theLexer;
  // errorEndPos = -1;
}

SQLParser::SQLParser(Lexer_ptr lexer, DbType_ptr dbType)
    : lexerHere(BOOL::FALSE)
{
  LOG_INFO << "in SQLParser";
  this->lexer = lexer;
  if (dbType != nullptr)
  {
    LOG_INFO << "dbType->name:" << dbType->name->c_str();
    this->dbType = dbType;
  }
  errorEndPos = -1;
}

SQLParser::SQLParser(string_ptr sql, DbType_ptr dbType, SQLParserFeature_list_ptr features)
    : SQLParser(Lexer_ptr(new Lexer(encode_util::UTF8ToUnicode(*sql), nullptr, dbType)), dbType)
{
  // Lexer::CommentHandler* tmp = new Lexer::CommentHandler();

  for (SQLParserFeature_ptr feature : *features)
  {
    config(feature, BOOL::TRUE);
  }

  this->lexer->nextToken();
  errorEndPos = -1;
}

Lexer_ptr SQLParser::getLexer()
{
  LOG_INFO;
  return lexer;
}

void SQLParser::accept(Token token)
{
  LOG_INFO << " lexer->token()->getName():" << lexer->token()->getName()->c_str();
  if (lexer->token()->name->c_str() == token.name->c_str())
  {
    LOG_INFO << "goto nextToken";
    lexer->nextToken();
  }
  else
  {
    setErrorEndPos(lexer->pos());
    std::stringstream stream;
    stream << "syntax error, expect " << token.getName()
           << ", actual " << lexer->token()->getName() << " " << lexer->stringVal()
           << ", pos " << lexer->pos();

    throw new ParserException(make_string_ptr(stream.str()));
  }
}

void SQLParser::match(Token token)
{
  if (lexer->token()->name->c_str() != token.name->c_str())
  {
    std::stringstream stream;
    // stream << "syntax error, expect " << token << ", actual " << lexer->token() << " " << lexer->stringVal();
    stream << "syntax error, expect "
           << " " << encode_util::UnicodeToUTF8(*lexer->stringVal()).c_str();
    throw new ParserException(make_string_ptr(stream.str()));
  }
}

void SQLParser::config(SQLParserFeature_ptr feature, BOOL_ptr state)
{
  this->lexer->config(feature, state);
}

string_ptr SQLParser::alias()
{
  string_ptr alias_ = make_string_ptr("");
  if (lexer->token()->name->c_str() == Token::LITERAL_ALIAS.name->c_str())
  {
    alias_ = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
    lexer->nextToken();
  }
  else if (lexer->token()->name->c_str() == Token::IDENTIFIER.name->c_str())
  {
    alias_ = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
    lexer->nextToken();
  }
  else if (lexer->token()->name->c_str() == Token::LITERAL_CHARS.name->c_str())
  {
    alias_ = make_string_ptr('\'' + encode_util::UnicodeToUTF8(*lexer->stringVal()).c_str() + '\'');
    lexer->nextToken();
  }
  else if (lexer->token()->name->c_str() == Token::LITERAL_FLOAT.name->c_str() &&
           dbType->name->c_str() == DbType::odps.name->c_str())
  {
    string_ptr numStr = make_string_ptr(encode_util::UnicodeToUTF8(lexer->numberString()));
    lexer->nextToken();
    if (lexer->token()->name->c_str() == Token::IDENTIFIER.name->c_str())
    {
      numStr->append(encode_util::UnicodeToUTF8(*lexer->stringVal()).c_str());
      lexer->nextToken();
    }
    return numStr;
  }
  else
  {
    if (lexer->token()->name->c_str() == Token::KEY.name->c_str() ||
        lexer->token()->name->c_str() == Token::INDEX.name->c_str() ||
        lexer->token()->name->c_str() == Token::CASE.name->c_str() ||
        lexer->token()->name->c_str() == Token::PCTFREE.name->c_str() ||
        lexer->token()->name->c_str() == Token::INITRANS.name->c_str() ||
        lexer->token()->name->c_str() == Token::MAXTRANS.name->c_str() ||
        lexer->token()->name->c_str() == Token::SEGMENT.name->c_str() ||
        lexer->token()->name->c_str() == Token::CREATION.name->c_str() ||
        lexer->token()->name->c_str() == Token::IMMEDIATE.name->c_str() ||
        lexer->token()->name->c_str() == Token::DEFERRED.name->c_str() ||
        lexer->token()->name->c_str() == Token::STORAGE.name->c_str() ||
        lexer->token()->name->c_str() == Token::NEXT.name->c_str() ||
        lexer->token()->name->c_str() == Token::MINEXTENTS.name->c_str() ||
        lexer->token()->name->c_str() == Token::MAXEXTENTS.name->c_str() ||
        lexer->token()->name->c_str() == Token::MAXSIZE.name->c_str() ||
        lexer->token()->name->c_str() == Token::PCTINCREASE.name->c_str() ||
        lexer->token()->name->c_str() == Token::FLASH_CACHE.name->c_str() ||
        lexer->token()->name->c_str() == Token::CELL_FLASH_CACHE.name->c_str() ||
        lexer->token()->name->c_str() == Token::NONE.name->c_str() ||
        lexer->token()->name->c_str() == Token::LOB.name->c_str() ||
        lexer->token()->name->c_str() == Token::STORE.name->c_str() ||
        lexer->token()->name->c_str() == Token::ROW.name->c_str() ||
        lexer->token()->name->c_str() == Token::CHUNK.name->c_str() ||
        lexer->token()->name->c_str() == Token::CACHE.name->c_str() ||
        lexer->token()->name->c_str() == Token::NOCACHE.name->c_str() ||
        lexer->token()->name->c_str() == Token::LOGGING.name->c_str() ||
        lexer->token()->name->c_str() == Token::NOCOMPRESS.name->c_str() ||
        lexer->token()->name->c_str() == Token::KEEP_DUPLICATES.name->c_str() ||
        lexer->token()->name->c_str() == Token::EXCEPTIONS.name->c_str() ||
        lexer->token()->name->c_str() == Token::PURGE.name->c_str() ||
        lexer->token()->name->c_str() == Token::INITIALLY.name->c_str() ||
        lexer->token()->name->c_str() == Token::END.name->c_str() ||
        lexer->token()->name->c_str() == Token::COMMENT.name->c_str() ||
        lexer->token()->name->c_str() == Token::ENABLE.name->c_str() ||
        lexer->token()->name->c_str() == Token::DISABLE.name->c_str() ||
        lexer->token()->name->c_str() == Token::SEQUENCE.name->c_str() ||
        lexer->token()->name->c_str() == Token::USER.name->c_str() ||
        lexer->token()->name->c_str() == Token::ANALYZE.name->c_str() ||
        lexer->token()->name->c_str() == Token::OPTIMIZE.name->c_str() ||
        lexer->token()->name->c_str() == Token::GRANT.name->c_str() ||
        lexer->token()->name->c_str() == Token::REVOKE.name->c_str() ||
        lexer->token()->name->c_str() == Token::FULL.name->c_str() ||
        lexer->token()->name->c_str() == Token::TO.name->c_str() ||
        lexer->token()->name->c_str() == Token::NEW.name->c_str() ||
        lexer->token()->name->c_str() == Token::INTERVAL.name->c_str() ||
        lexer->token()->name->c_str() == Token::LOCK.name->c_str() ||
        lexer->token()->name->c_str() == Token::LIMIT.name->c_str() ||
        lexer->token()->name->c_str() == Token::IDENTIFIED.name->c_str() ||
        lexer->token()->name->c_str() == Token::PASSWORD.name->c_str() ||
        lexer->token()->name->c_str() == Token::BINARY.name->c_str() ||
        lexer->token()->name->c_str() == Token::WINDOW.name->c_str() ||
        lexer->token()->name->c_str() == Token::OFFSET.name->c_str() ||
        lexer->token()->name->c_str() == Token::SHARE.name->c_str() ||
        lexer->token()->name->c_str() == Token::START.name->c_str() ||
        lexer->token()->name->c_str() == Token::CONNECT.name->c_str() ||
        lexer->token()->name->c_str() == Token::MATCHED.name->c_str() ||
        lexer->token()->name->c_str() == Token::ERRORS.name->c_str() ||
        lexer->token()->name->c_str() == Token::REJECT.name->c_str() ||
        lexer->token()->name->c_str() == Token::UNLIMITED.name->c_str() ||
        lexer->token()->name->c_str() == Token::BEGIN.name->c_str() ||
        lexer->token()->name->c_str() == Token::EXCLUSIVE.name->c_str() ||
        lexer->token()->name->c_str() == Token::MODE.name->c_str() ||
        lexer->token()->name->c_str() == Token::ADVISE.name->c_str() ||
        lexer->token()->name->c_str() == Token::TYPE.name->c_str() ||
        lexer->token()->name->c_str() == Token::CLOSE.name->c_str() ||
        lexer->token()->name->c_str() == Token::OPEN.name->c_str() ||
        lexer->token()->name->c_str() == Token::ANY.name->c_str() ||
        lexer->token()->name->c_str() == Token::CAST.name->c_str() ||
        lexer->token()->name->c_str() == Token::COMPUTE.name->c_str() ||
        lexer->token()->name->c_str() == Token::ESCAPE.name->c_str() ||
        lexer->token()->name->c_str() == Token::INTERSECT.name->c_str() ||
        lexer->token()->name->c_str() == Token::MERGE.name->c_str() ||
        lexer->token()->name->c_str() == Token::MINUS.name->c_str() ||
        lexer->token()->name->c_str() == Token::SOME.name->c_str() ||
        lexer->token()->name->c_str() == Token::TRUNCATE.name->c_str() ||
        lexer->token()->name->c_str() == Token::UNTIL.name->c_str() ||
        lexer->token()->name->c_str() == Token::VIEW.name->c_str() ||
        lexer->token()->name->c_str() == Token::FUNCTION.name->c_str() ||
        lexer->token()->name->c_str() == Token::DESC.name->c_str() ||
        lexer->token()->name->c_str() == Token::KILL.name->c_str() ||
        lexer->token()->name->c_str() == Token::SHOW.name->c_str() ||
        lexer->token()->name->c_str() == Token::XNULL.name->c_str() ||
        lexer->token()->name->c_str() == Token::ALL.name->c_str() ||
        lexer->token()->name->c_str() == Token::CONSTRAINT.name->c_str() ||
        lexer->token()->name->c_str() == Token::INNER.name->c_str() ||
        lexer->token()->name->c_str() == Token::LEFT.name->c_str() ||
        lexer->token()->name->c_str() == Token::RIGHT.name->c_str() ||
        lexer->token()->name->c_str() == Token::VALUES.name->c_str() ||
        lexer->token()->name->c_str() == Token::SCHEMA.name->c_str() ||
        lexer->token()->name->c_str() == Token::PARTITION.name->c_str() ||
        lexer->token()->name->c_str() == Token::UPDATE.name->c_str() ||
        lexer->token()->name->c_str() == Token::DO.name->c_str() ||
        lexer->token()->name->c_str() == Token::LOOP.name->c_str() ||
        lexer->token()->name->c_str() == Token::REPEAT.name->c_str() ||
        lexer->token()->name->c_str() == Token::DEFAULT.name->c_str() ||
        lexer->token()->name->c_str() == Token::LIKE.name->c_str() ||
        lexer->token()->name->c_str() == Token::IS.name->c_str() ||
        lexer->token()->name->c_str() == Token::UNIQUE.name->c_str() ||
        lexer->token()->name->c_str() == Token::CHECK.name->c_str() ||
        lexer->token()->name->c_str() == Token::INOUT.name->c_str() ||
        lexer->token()->name->c_str() == Token::DECLARE.name->c_str() ||
        lexer->token()->name->c_str() == Token::TABLE.name->c_str() ||
        lexer->token()->name->c_str() == Token::TRIGGER.name->c_str() ||
        lexer->token()->name->c_str() == Token::IN.name->c_str() ||
        lexer->token()->name->c_str() == Token::OUT.name->c_str() ||
        lexer->token()->name->c_str() == Token::BY.name->c_str() ||
        lexer->token()->name->c_str() == Token::EXCEPT.name->c_str() ||
        lexer->token()->name->c_str() == Token::TABLESPACE.name->c_str() ||
        lexer->token()->name->c_str() == Token::CREATE.name->c_str() ||
        lexer->token()->name->c_str() == Token::DELETE.name->c_str() ||
        lexer->token()->name->c_str() == Token::PRIMARY.name->c_str() ||
        lexer->token()->name->c_str() == Token::FOREIGN.name->c_str() ||
        lexer->token()->name->c_str() == Token::REFERENCES.name->c_str() ||
        lexer->token()->name->c_str() == Token::INTO.name->c_str() ||
        lexer->token()->name->c_str() == Token::USE.name->c_str() ||
        lexer->token()->name->c_str() == Token::LEAVE.name->c_str() ||
        lexer->token()->name->c_str() == Token::DISTRIBUTE.name->c_str() ||
        lexer->token()->name->c_str() == Token::AS.name->c_str() ||
        lexer->token()->name->c_str() == Token::FOR.name->c_str() ||
        lexer->token()->name->c_str() == Token::PARTITIONED.name->c_str() ||
        lexer->token()->name->c_str() == Token::REPLACE.name->c_str() ||
        lexer->token()->name->c_str() == Token::ALTER.name->c_str() ||
        lexer->token()->name->c_str() == Token::EXPLAIN.name->c_str() ||
        lexer->token()->name->c_str() == Token::ASC.name->c_str() ||
        lexer->token()->name->c_str() == Token::DATABASE.name->c_str() ||
        lexer->token()->name->c_str() == Token::XTRUE.name->c_str() ||
        lexer->token()->name->c_str() == Token::XFALSE.name->c_str() ||
        lexer->token()->name->c_str() == Token::OUTER.name->c_str() ||
        lexer->token()->name->c_str() == Token::DROP.name->c_str())
    {
      alias_ = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
      lexer->nextToken();
      return alias_;
    }
    else if (lexer->token()->name->c_str() == Token::GROUP.name->c_str() ||
             lexer->token()->name->c_str() == Token::ORDER.name->c_str())
    {
      if (dbType->name->c_str() == DbType::odps.name->c_str() ||
          dbType->name->c_str() == DbType::hive.name->c_str())
      {
        Lexer_SavePoint_ptr mark = lexer->mark();
        alias_ = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
        lexer->nextToken();
        if (lexer->token()->name->c_str() == Token::BY.name->c_str())
        {
          lexer->reset(mark);
          alias_ = make_string_ptr("");
        }
      }
    }
    else if (lexer->token()->name->c_str() == Token::QUES.name->c_str())
    {
      alias_ = make_string_ptr("?");
      lexer->nextToken();
      return alias_;
    }
    else if (lexer->token()->name->c_str() == Token::UNION.name->c_str())
    {
      Lexer_SavePoint_ptr mark = lexer->mark();
      string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
      lexer->nextToken();
      if (lexer->token()->name->c_str() == Token::ALL.name->c_str())
      {
        lexer->reset(mark);
        string_ptr tmp = make_string_ptr("");
        return tmp;
      }
      else
      {
        return strVal;
      }
    }
  }
  return alias_;
}

string_ptr SQLParser::tableAlias()
{
  return tableAlias(BOOL::FALSE);
}

string_ptr SQLParser::tableAlias(BOOL_ptr must)
{
  Token_ptr token = lexer->token();
  if (token->name->c_str() == Token::CONNECT.name->c_str() ||
      token->name->c_str() == Token::START.name->c_str() ||
      token->name->c_str() == Token::SELECT.name->c_str() ||
      token->name->c_str() == Token::FROM.name->c_str() ||
      token->name->c_str() == Token::WHERE.name->c_str())
  {
    if (token->name->c_str() == Token::WHERE.name->c_str() &&
        dbType->name->c_str() == DbType::odps.name->c_str())
    {
      return NULL;
    }

    if (must)
    {
      std::string tmp = "illegal alias. ";
      tmp += encode_util::UnicodeToUTF8(lexer->info());
      throw new ParserException(make_string_ptr(tmp));
    }
    return NULL;
  }

  if (token->name->c_str() == Token::IDENTIFIER.name->c_str())
  {
    string_ptr ident = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
    long hash = lexer->hashLCase();
    if (isEnabled(SQLParserFeature_ptr(new SQLParserFeature(SQLParserFeature::IgnoreNameQuotes.mask, SQLParserFeature::IgnoreNameQuotes.name))) &&
        ident->length() > 1)
    {
      ident = StringUtils::removeNameQuotes(ident);
    }

    if (hash == FnvHash::Constants::START ||
        hash == FnvHash::Constants::CONNECT ||
        hash == FnvHash::Constants::NATURAL ||
        hash == FnvHash::Constants::CROSS ||
        hash == FnvHash::Constants::OFFSET ||
        hash == FnvHash::Constants::LIMIT)
    {
      if (must)
      {
        std::string tmp = "illegal alias. ";
        tmp += encode_util::UnicodeToUTF8(lexer->info());
        throw new ParserException(make_string_ptr(tmp));
      }

      Lexer_SavePoint_ptr mark = lexer->mark();
      lexer->nextToken();
      if (lexer->token()->name->c_str() == Token::XEOF.name->c_str() ||
          lexer->token()->name->c_str() == Token::COMMA.name->c_str() ||
          lexer->token()->name->c_str() == Token::WHERE.name->c_str() ||
          lexer->token()->name->c_str() == Token::INNER.name->c_str() ||
          lexer->token()->name->c_str() == Token::LEFT.name->c_str() ||
          lexer->token()->name->c_str() == Token::RIGHT.name->c_str() ||
          lexer->token()->name->c_str() == Token::FULL.name->c_str() ||
          lexer->token()->name->c_str() == Token::ON.name->c_str() ||
          lexer->token()->name->c_str() == Token::GROUP.name->c_str() ||
          lexer->token()->name->c_str() == Token::ORDER.name->c_str())
      {
        return ident;
      }
      else if (lexer->token()->name->c_str() == Token::JOIN.name->c_str())
      {
        if (hash != FnvHash::Constants::NATURAL &&
            hash != FnvHash::Constants::CROSS)
        {
          return ident;
        }
        lexer->reset(mark);
      }
      else
      {
        lexer->reset(mark);
      }

      return NULL;
    }

    if (!must)
    {
      if (hash == FnvHash::Constants::MODEL)
      {
        Lexer_SavePoint_ptr mark = lexer->mark();
        lexer->nextToken();
        if (lexer->token()->name->c_str() == Token::PARTITION.name->c_str() ||
            lexer->identifierEquals(FnvHash::Constants::DIMENSION) ||
            lexer->identifierEquals(FnvHash::Constants::IGNORE) ||
            lexer->identifierEquals(FnvHash::Constants::KEEP))
        {
          lexer->reset(mark);
          return NULL;
        }
        return ident;
      }
      else if (hash == FnvHash::Constants::WINDOW)
      {
        Lexer_SavePoint_ptr mark = lexer->mark();
        lexer->nextToken();
        if (lexer->token()->name->c_str() == Token::IDENTIFIER.name->c_str())
        {
          lexer->reset(mark);
          return NULL;
        }
        return ident;
      }
      else if (hash == FnvHash::Constants::DISTRIBUTE ||
               hash == FnvHash::Constants::SORT ||
               hash == FnvHash::Constants::CLUSTER ||
               hash == FnvHash::Constants::ZORDER)
      {
        Lexer_SavePoint_ptr mark = lexer->mark();
        lexer->nextToken();
        if (lexer->token()->name->c_str() == Token::BY.name->c_str())
        {
          lexer->reset(mark);
          return NULL;
        }
        return ident;
      }
      else if (hash == FnvHash::Constants::ASOF &&
               dbType->name->c_str() == DbType::clickhouse.name->c_str())
      {
        Lexer_SavePoint_ptr mark = lexer->mark();
        lexer->nextToken();
        if (lexer->token()->name->c_str() == Token::LEFT.name->c_str() ||
            lexer->token()->name->c_str() == Token::JOIN.name->c_str())
        {
          lexer->reset(mark);
          return NULL;
        }
        return ident;
      }
    }
  }

  if (!must)
  {
    if (lexer->token()->name->c_str() == Token::LEFT.name->c_str() ||
        lexer->token()->name->c_str() == Token::RIGHT.name->c_str() ||
        lexer->token()->name->c_str() == Token::INNER.name->c_str() ||
        lexer->token()->name->c_str() == Token::FULL.name->c_str())
    {
      Lexer_SavePoint_ptr mark = lexer->mark();
      string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
      lexer->nextToken();
      if (lexer->token()->name->c_str() == Token::OUTER.name->c_str() ||
          lexer->token()->name->c_str() == Token::JOIN.name->c_str() ||
          lexer->identifierEquals(FnvHash::Constants::ANTI) ||
          lexer->identifierEquals(FnvHash::Constants::SEMI))
      {
        lexer->reset(mark);
        return NULL;
      }
      else
      {
        return strVal;
      }
    }
    else if (lexer->token()->name->c_str() == Token::OUTER.name->c_str() ||
             lexer->token()->name->c_str() == Token::IN.name->c_str() ||
             lexer->token()->name->c_str() == Token::SET.name->c_str() ||
             lexer->token()->name->c_str() == Token::BY.name->c_str())
    {
      Lexer_SavePoint_ptr mark = lexer->mark();
      string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
      lexer->nextToken();
      if (lexer->token()->name->c_str() == Token::WHERE.name->c_str() ||
          lexer->token()->name->c_str() == Token::GROUP.name->c_str() ||
          lexer->token()->name->c_str() == Token::ORDER.name->c_str() ||
          lexer->token()->name->c_str() == Token::LEFT.name->c_str() ||
          lexer->token()->name->c_str() == Token::RIGHT.name->c_str() ||
          lexer->token()->name->c_str() == Token::FULL.name->c_str() ||
          lexer->token()->name->c_str() == Token::RPAREN.name->c_str() ||
          lexer->token()->name->c_str() == Token::ON.name->c_str() ||
          lexer->token()->name->c_str() == Token::JOIN.name->c_str() ||
          lexer->token()->name->c_str() == Token::SEMI.name->c_str())
      {
        return strVal;
      }
      else
      {
        lexer->reset(mark);
      }
    }
    else if (lexer->token()->name->c_str() == Token::FOR.name->c_str() ||
             lexer->token()->name->c_str() == Token::GRANT.name->c_str() ||
             lexer->token()->name->c_str() == Token::CHECK.name->c_str() ||
             lexer->token()->name->c_str() == Token::LEAVE.name->c_str() ||
             lexer->token()->name->c_str() == Token::TRIGGER.name->c_str() ||
             lexer->token()->name->c_str() == Token::CREATE.name->c_str() ||
             lexer->token()->name->c_str() == Token::ASC.name->c_str() ||
             lexer->token()->name->c_str() == Token::INOUT.name->c_str() ||
             lexer->token()->name->c_str() == Token::DESC.name->c_str() ||
             lexer->token()->name->c_str() == Token::SCHEMA.name->c_str() ||
             lexer->token()->name->c_str() == Token::IS.name->c_str() ||
             lexer->token()->name->c_str() == Token::DECLARE.name->c_str() ||
             lexer->token()->name->c_str() == Token::DROP.name->c_str() ||
             lexer->token()->name->c_str() == Token::FETCH.name->c_str() ||
             lexer->token()->name->c_str() == Token::LOCK.name->c_str())
    {
      if (dbType->name->c_str() == DbType::odps.name->c_str() ||
          dbType->name->c_str() == DbType::hive.name->c_str())
      {
        string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
        lexer->nextToken();
        return strVal;
      }
    }
    else if (lexer->token()->name->c_str() == Token::PARTITION.name->c_str())
    {
      if (dbType->name->c_str() == DbType::odps.name->c_str() ||
          dbType->name->c_str() == DbType::hive.name->c_str())
      {
        Lexer_SavePoint_ptr mark = lexer->mark();
        string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
        lexer->nextToken();
        if (lexer->token()->name->c_str() == Token::LPAREN.name->c_str())
        {
          lexer->reset(mark);
          return NULL;
        }
        return strVal;
      }
    }
    else if (lexer->token()->name->c_str() == Token::TABLE.name->c_str())
    {
      if (dbType->name->c_str() == DbType::odps.name->c_str())
      {
        Lexer_SavePoint_ptr mark = lexer->mark();
        string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
        lexer->nextToken();
        if (lexer->token()->name->c_str() == Token::FROM.name->c_str() ||
            lexer->token()->name->c_str() == Token::GROUP.name->c_str() ||
            lexer->token()->name->c_str() == Token::ORDER.name->c_str() ||
            lexer->token()->name->c_str() == Token::ON.name->c_str())
        {
          return strVal;
        }
        else
        {
          lexer->reset(mark);
        }
      }
    }
    else if (lexer->token()->name->c_str() == Token::SHOW.name->c_str() ||
             lexer->token()->name->c_str() == Token::REFERENCES.name->c_str() ||
             lexer->token()->name->c_str() == Token::REPEAT.name->c_str() ||
             lexer->token()->name->c_str() == Token::USE.name->c_str() ||
             lexer->token()->name->c_str() == Token::MOD.name->c_str() ||
             lexer->token()->name->c_str() == Token::OUT.name->c_str())
    {
      string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
      lexer->nextToken();
      return strVal;
    }
  }
  else if (lexer->token()->name->c_str() == Token::QUALIFY.name->c_str())
  {
    string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
    Lexer_SavePoint_ptr mark = lexer->mark();
    lexer->nextToken();
    if (lexer->token()->name->c_str() != Token::WHERE.name->c_str() &&
        lexer->token()->name->c_str() != Token::GROUP.name->c_str() &&
        lexer->token()->name->c_str() != Token::HAVING.name->c_str() &&
        lexer->token()->name->c_str() != Token::WINDOW.name->c_str() &&
        lexer->token()->name->c_str() != Token::ORDER.name->c_str() &&
        lexer->token()->name->c_str() != Token::LIMIT.name->c_str() &&
        lexer->token()->name->c_str() != Token::XEOF.name->c_str() &&
        lexer->token()->name->c_str() != Token::COMMA.name->c_str())
    {
      lexer->reset(mark);
      return NULL;
    }
    else
    {
      return strVal;
    }
  }
  else if (lexer->token()->name->c_str() == Token::DISTRIBUTE.name->c_str())
  {
    string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
    Lexer_SavePoint_ptr mark = lexer->mark();
    lexer->nextToken();
    if (lexer->token()->name->c_str() == Token::BY.name->c_str())
    {
      lexer->reset(mark);
      return NULL;
    }
    else
    {
      return strVal;
    }
  }
  else if (lexer->token()->name->c_str() == Token::MINUS.name->c_str() ||
           lexer->token()->name->c_str() == Token::EXCEPT.name->c_str() ||
           lexer->token()->name->c_str() == Token::LIMIT.name->c_str() ||
           lexer->token()->name->c_str() == Token::BETWEEN.name->c_str())
  {
    if (dbType->name->c_str() == DbType::odps.name->c_str())
    {
      Lexer_SavePoint_ptr mark = lexer->mark();
      string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
      lexer->nextToken();
      if (lexer->token()->name->c_str() == Token::XEOF.name->c_str() ||
          lexer->token()->name->c_str() == Token::COMMA.name->c_str() ||
          lexer->token()->name->c_str() == Token::WHERE.name->c_str() ||
          lexer->token()->name->c_str() == Token::GROUP.name->c_str() ||
          lexer->token()->name->c_str() == Token::ORDER.name->c_str() ||
          lexer->token()->name->c_str() == Token::LEFT.name->c_str() ||
          lexer->token()->name->c_str() == Token::RIGHT.name->c_str() ||
          lexer->token()->name->c_str() == Token::FULL.name->c_str() ||
          lexer->token()->name->c_str() == Token::RPAREN.name->c_str() ||
          lexer->token()->name->c_str() == Token::ON.name->c_str() ||
          lexer->token()->name->c_str() == Token::JOIN.name->c_str() ||
          lexer->token()->name->c_str() == Token::SEMI.name->c_str())
      {
        return strVal;
      }
      else
      {
        lexer->reset(mark);
      }
    }
  }
  else if (lexer->token()->name->c_str() == Token::UNION.name->c_str())
  {
    Lexer_SavePoint_ptr mark = lexer->mark();
    string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
    lexer->nextToken();
    if (lexer->token()->name->c_str() == Token::GROUP.name->c_str() ||
        lexer->token()->name->c_str() == Token::ORDER.name->c_str() ||
        lexer->token()->name->c_str() == Token::SEMI.name->c_str() ||
        lexer->token()->name->c_str() == Token::LEFT.name->c_str() ||
        lexer->token()->name->c_str() == Token::RIGHT.name->c_str() ||
        lexer->token()->name->c_str() == Token::INNER.name->c_str() ||
        lexer->token()->name->c_str() == Token::JOIN.name->c_str() ||
        lexer->token()->name->c_str() == Token::RPAREN.name->c_str())
    {
      return strVal;
    }
    else
    {
      lexer->reset(mark);
    }
  }

  if (must)
  {
    if (dbType->name->c_str() == DbType::odps.name->c_str())
    {
      if (lexer->token()->name->c_str() == Token::GROUP.name->c_str() ||
          lexer->token()->name->c_str() == Token::ORDER.name->c_str())
      {
        Lexer_SavePoint_ptr mark = lexer->mark();
        string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
        lexer->nextToken();
        if (lexer->token()->name->c_str() == Token::BY.name->c_str())
        {
          lexer->reset(mark);
          return NULL;
        }
        else
        {
          return strVal;
        }
      }
      else if (lexer->token()->name->c_str() == Token::UNION.name->c_str())
      {
        Lexer_SavePoint_ptr mark = lexer->mark();
        string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
        lexer->nextToken();
        if (lexer->token()->name->c_str() == Token::ALL.name->c_str())
        {
          lexer->reset(mark);
          return NULL;
        }
        else
        {
          return strVal;
        }
      }
    }
    else if (lexer->token()->name->c_str() == Token::LIMIT.name->c_str())
    {
      Lexer_SavePoint_ptr mark = lexer->mark();
      string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
      lexer->nextToken();
      if (lexer->token()->name->c_str() == Token::LITERAL_INT.name->c_str())
      {
        lexer->reset(mark);
        return NULL;
      }
      else
      {
        return strVal;
      }
    }
    else if (lexer->token()->name->c_str() == Token::BETWEEN.name->c_str())
    {
      Lexer_SavePoint_ptr mark = lexer->mark();
      string_ptr strVal = make_string_ptr(encode_util::UnicodeToUTF8(*lexer->stringVal()));
      lexer->nextToken();
      if (lexer->token()->name->c_str() == Token::GROUP.name->c_str() ||
          lexer->token()->name->c_str() == Token::ORDER.name->c_str() ||
          lexer->token()->name->c_str() == Token::SEMI.name->c_str() ||
          lexer->token()->name->c_str() == Token::LEFT.name->c_str() ||
          lexer->token()->name->c_str() == Token::RIGHT.name->c_str() ||
          lexer->token()->name->c_str() == Token::INNER.name->c_str() ||
          lexer->token()->name->c_str() == Token::JOIN.name->c_str())
      {
        return strVal;
      }
      else
      {
        lexer->reset(mark);
        return NULL;
      }
    }

    return this->alias();
  }

  return this->as();
}

int SQLParser::acceptInteger()
{
  if (lexer->token()->name->c_str() == Token::LITERAL_INT.name->c_str())
  {
    int intVal = lexer->integerValue();
    lexer->nextToken();
    return intVal;
  }
  else
  {
    std::string tmp = "syntax error, expect int, actual ";
    tmp += lexer->token()->name->c_str();
    tmp += " ";
    tmp += encode_util::UnicodeToUTF8(*lexer->stringVal()).c_str();
    throw new ParserException(make_string_ptr(tmp));
  }
}